
package com.jwong.common.util;

import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalField;
import java.time.temporal.WeekFields;
import java.util.*;

/**
 * 时间处理工具类
 */
@Slf4j
public class DateUtils {
	private static Logger logger = LoggerFactory.getLogger(DateUtils.class);

	public enum QueryTimeDimension {
		TODAY, THIS_WEEK, THIS_MONTH, THIS_TERM, CUSTOM
	}

	/** The Constant YEAR. */
	public final static String YEAR = " year ";

	/** The Constant MONTH. */
	public final static String MONTH = " month ";

	/** The Constant DAY. */
	public final static String DAY = " day ";

	/** The Constant WEEK. */
	public final static String WEEK = " week ";

	/** The Constant HOUR. */
	public final static String HOUR = " hour ";

	/** The Constant MINUTE. */
	public final static String MINUTE = " minute ";

	/** The Constant SECOND. */
	public final static String SECOND = " second ";

	/** The Constant YEAR_MONTH_FORMAT.<br>yyyy-MM */
	public static final String YEAR_MONTH_FORMAT = "yyyy-MM";

	/** The Constant YEAR_MONTH_FORMAT_CN.<br>yyyy年MM月 */
	public static final String YEAR_MONTH_FORMAT_CN = "yyyy年MM月";

	/** The Constant DATE_TIME_FORMAT.<br>yyyy-MM-dd HH:mm:ss */
	public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
	
	/** The Constant DATE_TIME_FORMAT_MIN.<br>yyyyMMddHHmmss */
	public static final String DATE_TIME_FORMAT_MIN = "yyyyMMddHHmmss";

	/** The Constant DATE_FORMAT.<br>yyyy-MM-dd */
	public static final String DATE_FORMAT = "yyyy-MM-dd";

	/** The Constant DATE_WEEK_FORMAT.<br>MM-dd EEEE */
	public static final String DATE_WEEK_FORMAT = "MM-dd EEEE";

	/** The Constant TIME_MIN_FORMAT.<br>HH:mm */
	public static final String TIME_MIN_FORMAT = "HH:mm";

	/** The Constant MONTH_DAY_FORMAT.<br>MM-dd */
	public static final String MONTH_DAY_FORMAT = "MM-dd";

	public static final String EVERY_TIME_FORMAT="HH:mm:ss";
	/**
	 * 判断参数是否等于null或者空
	 * 
	 * @param param
	 * @return
	 */
	public static boolean checkParam(Object param) {
		if (null == param || "".equals(param)) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 得到当前系统时间:毫秒数
	 * 
	 * @return
	 */
	public static long getCurrentTimeMillis() {
		return System.currentTimeMillis();
	}

	/**
	 * 得到当前系统时间:无任何格式化
	 * 
	 * @return 格林威治时间
	 */
	public static Date getCurrentDate() {
		return new Date(getCurrentTimeMillis());
	}
	
	/**
	 * add by liy@2015/01/16,mysql不支持毫秒数
	 * 得到当前系统时间:无毫秒数
	 * 
	 * @return 格林威治时间
	 */
	public static Date getCurrentDateWithoutTimeMillis() {
		Date date = getCurrentDate();
		SimpleDateFormat dateFormat = new SimpleDateFormat(DateUtils.DATE_TIME_FORMAT);
		return dateFormat.parse(dateFormat.format(date),new ParsePosition(0));
	}

	/**
	 * 得到当前系统时间并转化为字符串：系统默认显示格式
	 * 
	 * @return 系统默认时间显示格式 19位字符串
	 */
	public static String getCurrentFormatDateTime() {
		Date date = getCurrentDate();
		SimpleDateFormat dateFormat = new SimpleDateFormat(DateUtils.DATE_TIME_FORMAT);
		return dateFormat.format(date);
	}

	/**
	 * 得到当前系统日期并转化为字符串：系统默认显示格式
	 * 
	 * @return 系统默认日期显示格式 10位字符串
	 */
	public static String getCurrentFormatDate() {
		Date date = new Date(getCurrentTimeMillis());
		SimpleDateFormat dateFormat = new SimpleDateFormat(DateUtils.DATE_FORMAT);
		return dateFormat.format(date);
	}

	/**
	 * 得到当前系统日期和星期并转化为字符串：系统默认显示格式
	 * 
	 * @return 系统默认日期和星期显示格式 15位字符串
	 */
	public static String getCurrentFormatDateWeek() {
		Date date = new Date(getCurrentTimeMillis());
		SimpleDateFormat dateFormat = new SimpleDateFormat(DateUtils.DATE_WEEK_FORMAT);
		return dateFormat.format(date);
	}

	/**
	 * 得到当前系统时间并转化为字符串：指定显示格式
	 * 
	 * @param pattern
	 *                e.g.DATE_FORMAT_8 = "yyyyMMdd"; DATE_TIME_FORMAT_14 = "yyyyMMddHHmmss"; 或者类似于二者的格式 <br>
	 *                e.g."yyyyMMddHH"，"yyyyMM"
	 * @return
	 */
	public static String getCurrentCustomizeFormatDate(String pattern) {
		if (checkParam(pattern)) {
			return "";
		}
		Date date = getCurrentDate();
		SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
		return dateFormat.format(date);
	}

	/**
	 * 输入日期，按照指定格式返回
	 * 
	 * @param date
	 * @param pattern
	 *                e.g.DATE_FORMAT_8 = "yyyyMMdd"; DATE_TIME_FORMAT_14 = "yyyyMMddHHmmss"; 或者类似于二者的格式 <br>
	 *                e.g."yyyyMMddHH"，"yyyyMM"
	 * @return
	 */
	public static String formatDate(Date date, String pattern) {
		if (checkParam(pattern) || checkParam(date)) {
			return "";
		}
		SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);

		return dateFormat.format(date);
	}

	/**
	 * 输入日期，按照指定格式和地区标识符返回
	 * 
	 * @param date
	 * @param pattern
	 *                e.g.DATE_FORMAT_8 = "yyyyMMdd"; DATE_TIME_FORMAT_14 = "yyyyMMddHHmmss"; 或者类似于二者的格式 <br>
	 *                e.g."yyyyMMddHH"，"yyyyMM"
	 * @param locale
	 *                国家地区， e.g.new Locale("zh","CN","") 中国 Locale.getDefault();
	 * @return
	 */
	public static String formatDate(Date date, String pattern, Locale locale) {
		if (checkParam(pattern) || checkParam(date)) {
			return "";
		}
		if (checkParam(locale)) {
			locale = Locale.getDefault();
		}
		SimpleDateFormat dateFormat = new SimpleDateFormat(pattern, locale);
		return dateFormat.format(date);
	}

	/**
	 * 将时间字符串按照默认格式DATE_FORMAT = "yyyy-MM-dd"，转换为Date
	 * 
	 * @param dateStr
	 * @return
	 */
	public static Date parseStrToDate(String dateStr) {
		if (checkParam(dateStr)) {
			return null;
		}
		SimpleDateFormat dateFormat = new SimpleDateFormat(DateUtils.DATE_FORMAT);
		return dateFormat.parse(dateStr, new ParsePosition(0));
	}

	/**
	 * 将时间字符串按照默认格式DATE_TIME_FORMAT ="yyyy-MM-dd HH:mm:ss",转换为Date
	 * 
	 * @param dateStr
	 * @return
	 */
	public static Date parseStrToDateTime(String dateStr) {
		if (checkParam(dateStr)) {
			return null;
		}
		SimpleDateFormat dateFormat = new SimpleDateFormat(DateUtils.DATE_TIME_FORMAT);
		return dateFormat.parse(dateStr, new ParsePosition(0));
	}

	/**
	 * 将时间字符串按照默认格式DATE_FORMAT = "yyyy-MM-dd"，转换为Calender
	 * 
	 * @param dateStr
	 * @return
	 */
	public static Calendar parseStrToCalendar(String dateStr) {
		if (checkParam(dateStr)) {
			return null;
		}
		Date date = parseStrToDateTime(dateStr);
		Locale locale = Locale.getDefault();
		Calendar cal = new GregorianCalendar(locale);
		cal.setTime(date);
		return cal;
	}

	/**
	 * 将日期字符串转换成日期时间字符串
	 * 
	 * @param dateStr
	 * @return
	 */
	public static String parseDateStrToDateTimeStr(String dateStr) {
		if (checkParam(dateStr)) {
			return "";
		}
		SimpleDateFormat dateFormat = new SimpleDateFormat(DateUtils.DATE_FORMAT);
		Date date = dateFormat.parse(dateStr, new ParsePosition(0));
		return formatDate(date, DateUtils.DATE_TIME_FORMAT);
	}

	/**
	 * 将时间或者时间日期字符串按照指定格式转换为Date
	 * 
	 * @param dateStr
	 * @param pattern
	 * @return
	 */
	public static Date parseStrToCustomPatternDate(String dateStr, String pattern) {
		if (checkParam(pattern) || checkParam(dateStr)) {
			return null;
		}
		SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
		Date date = dateFormat.parse(dateStr, new ParsePosition(0));
		return date;
	}

	/**
	 * 将时间字符串从一种格式转换成另一种格式.
	 * 
	 * @param dateStr
	 *                e.g. String dateStr = "2006-10-12 16:23:06";
	 * @param patternFrom
	 *                e.g. DatePattern.DATE_TIME_FORMAT
	 * @param patternTo
	 *                e.g. DatePattern.DATE_TIME_FORMAT_14
	 * @return
	 */
	public static String convertDatePattern(String dateStr, String patternFrom, String patternTo) {
		if (checkParam(patternFrom) || checkParam(patternTo) || checkParam(dateStr)) {
			return "";
		}
		//当时间字符串缺少后面部分时，自动修正格式字符串
		if(dateStr.length() < patternFrom.length()){
			patternFrom = patternFrom.substring(0, dateStr.length());
		}
		SimpleDateFormat dateFormat = new SimpleDateFormat(patternFrom);
		Date date = dateFormat.parse(dateStr, new ParsePosition(0));
		return formatDate(date, patternTo);
	}

	/**
	 * 日期天数增加
	 * 
	 * @param date
	 * @param days
	 * @return
	 */
	public static Date addDays(Date date, int days) {
		if (checkParam(date)) {
			return null;
		}
		if (0 == days) {
			return date;
		}
		Locale locale = Locale.getDefault();
		Calendar calendar = new GregorianCalendar(locale);
		calendar.setTime(date);
		calendar.add(Calendar.DAY_OF_MONTH, days);
		return calendar.getTime();
	}

	/**
	 * 日期天数减少
	 * 
	 * @param date
	 * @param days
	 * @return
	 */
	public static Date minusDays(Date date, int days) {
		return addDays(date, (0 - days));
	}

	public static int differentDays(Date before, Date after) {
		return  (int) ((after.getTime() - before.getTime()) / (1000*3600*24));
	}

	public static int distanceDay(Date largeDay, Date smallDay) {
		int day = (int) ((largeDay.getTime() - smallDay.getTime()) / (1000 * 60 * 60 * 24));
		return day;
	}

	/**
	 * 日期小时增加
	 * 
	 * @param date
	 * @param hours
	 * @return
	 */
	public static Date addHours(Date date, int hours) {
		if (checkParam(date)) {
			return null;
		}
		if (0 == hours) {
			return date;
		}
		Locale locale = Locale.getDefault();
		Calendar calendar = new GregorianCalendar(locale);
		calendar.setTime(date);
		calendar.add(Calendar.HOUR_OF_DAY, hours);
		return calendar.getTime();
	}
	
	/**
	 * 日期分钟增加
	 * 
	 * @param date
	 * @param minute
	 * @return
	 */
	public static Date addMinutes(Date date, int minute) {
		if (checkParam(date)) {
			return null;
		}
		if (0 == minute) {
			return date;
		}
		Locale locale = Locale.getDefault();
		Calendar calendar = new GregorianCalendar(locale);
		calendar.setTime(date);
		calendar.add(Calendar.MINUTE, minute);
		return calendar.getTime();
	}
	
	/**
	 * 日期秒增加
	 * 
	 * @param date
	 * @param seconds
	 * @return
	 */
	public static Date addSeconds(Date date, int seconds) {
		if (checkParam(date)) {
			return null;
		}
		if (0 == seconds) {
			return date;
		}
		Locale locale = Locale.getDefault();
		Calendar calendar = new GregorianCalendar(locale);
		calendar.setTime(date);
		calendar.add(Calendar.SECOND, seconds);
		return calendar.getTime();
	}
	
	/**
	 * 按时间格式相加
	 * 
	 * @param dateStr
	 *                原来的时间
	 * @param pattern
	 *                时间格式
	 * @param type
	 *                "year"年、"month"月、"day"日、"week"周、 "hour"时、"minute"分、"second"秒
	 *                通过常量来设置,e.g.DayInfoUtil.YEAR
	 * @param count
	 *                相加数量
	 * @return
	 */
	public static String addDate(String dateStr, String pattern, String type, int count) {
		if (checkParam(dateStr) || checkParam(pattern) || checkParam(type)) {
			return "";
		}
		if (0 == count) {
			return dateStr;
		}
		Date date = parseStrToCustomPatternDate(dateStr, pattern);
		Locale locale = Locale.getDefault();
		Calendar calendar = new GregorianCalendar(locale);
		calendar.setTime(date);

		if (DateUtils.YEAR.equals(type)) {
			calendar.add(Calendar.YEAR, count);
		} else if (DateUtils.MONTH.equals(type)) {
			calendar.add(Calendar.MONTH, count);
		} else if (DateUtils.DAY.equals(type)) {
			calendar.add(Calendar.DAY_OF_MONTH, count);
		} else if (DateUtils.WEEK.equals(type)) {
			calendar.add(Calendar.WEEK_OF_MONTH, count);
		} else if (DateUtils.HOUR.equals(type)) {
			calendar.add(Calendar.HOUR, count);
		} else if (DateUtils.MINUTE.equals(type)) {
			calendar.add(Calendar.MINUTE, count);
		} else if (DateUtils.SECOND.equals(type)) {
			calendar.add(Calendar.SECOND, count);
		} else {
			return "";
		}

		return formatDate(calendar.getTime(), pattern);
	}

	/**
	 * 那时间格式相减
	 * 
	 * @param pattern
	 * @param type
	 * @param count
	 * @return
	 */
	public static Date minusDate(Date date, String pattern, String type, int count) {
		String dateStr = DateUtils.formatDate(date, pattern);
		 dateStr = addDate(dateStr, pattern, type, (0 - count));
		 return DateUtils.parseStrToCustomPatternDate(dateStr, pattern);
	}

	/**
	 * 那时间格式相减
	 * 
	 * @param dateStr
	 * @param pattern
	 * @param type
	 * @param count
	 * @return
	 */
	public static String minusDate(String dateStr, String pattern, String type, int count) {
		return addDate(dateStr, pattern, type, (0 - count));
	}

	/**
	 * 日期大小比较
	 * 
	 * @param dateStr1
	 * @param dateStr2
	 * @param pattern
	 * @return
	 */
	public static int compareDate(String dateStr1, String dateStr2, String pattern) {
		if (checkParam(dateStr1) || checkParam(dateStr2) || checkParam(pattern)) {
			return 999;
		}
		Date date1 = parseStrToCustomPatternDate(dateStr1, pattern);
		Date date2 = parseStrToCustomPatternDate(dateStr2, pattern);

		return date1.compareTo(date2);
	}

	/**
	 * 日期大小比较
	 * 
	 * @param dateOne
	 * @param dateOther
	 * @return
	 * 
	 *         int
	 * 
	 *         Created on Aug 15, 2007 12:41:30 AM
	 */
	public static long compareDate(Date dateOne, Date dateOther) {
		return dateOne.getTime() - dateOther.getTime();
	}

	
	/**
	 * 日期大小比较
	 * 
	 * @param dateOne
	 * @param dateOther
	 * @return
	 * 
	 *         int
	 * 
	 *         Created on Aug 15, 2007 12:41:30 AM
	 */
	public static boolean compareTime(Date dateOne, Date dateOther) {
		return (dateOne.getTime() - dateOther.getTime())>0;
	}
	/**
	 * 获得这个月的第一天
	 * 
	 * @param dateStr
	 * @return
	 */
	public static String getFirstDayInMonth(String dateStr) {
		if (checkParam(dateStr)) {
			return "";
		}
		Date date = parseStrToDate(dateStr);
		Locale locale = Locale.getDefault();
		Calendar calendar = new GregorianCalendar(locale);
		calendar.setTime(date);
		int firstDay = calendar.getActualMinimum(Calendar.DAY_OF_MONTH);
		calendar.set(Calendar.DAY_OF_MONTH, firstDay);
		return formatDate(calendar.getTime(), DateUtils.DATE_FORMAT);
	}

	/**
	 * 获得这个月的最后一天
	 * 
	 * @param dateStr
	 * @return
	 */
	public static String getLastDayInMonth(String dateStr) {
		if (checkParam(dateStr)) {
			return "";
		}
		Date date = parseStrToDate(dateStr);
		Locale locale = Locale.getDefault();
		Calendar calendar = new GregorianCalendar(locale);
		calendar.setTime(date);
		int lastDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
		calendar.set(Calendar.DAY_OF_MONTH, lastDay);
		return DateUtils.formatDate(calendar.getTime(), DateUtils.DATE_FORMAT);
	}

	/**
	 * 获得这周的第一天
	 * 
	 * @param dateStr
	 * @return
	 */
	public static String getFirstDayInWeek(String dateStr) {
		if (checkParam(dateStr)) {
			return "";
		}
		Date date = parseStrToDate(dateStr);
		Locale locale = Locale.getDefault();
		Calendar calendar = new GregorianCalendar(locale);
		calendar.setTime(date);
		int firstDay = calendar.getActualMinimum(Calendar.DAY_OF_WEEK);
		calendar.set(Calendar.DAY_OF_WEEK, firstDay);
		return DateUtils.formatDate(calendar.getTime(), DateUtils.DATE_TIME_FORMAT);
	}

	public static String getFirstDayInWeek(Date date, String format) {
		return DateUtils.formatDate(getFirstDayInWeek(date), format);
	}
	
	
	 public static Date getFirstDayInWeek(Date date) {    
          Calendar cal = Calendar.getInstance();    
          cal.setTime(date);    
          cal.add(Calendar.DAY_OF_MONTH, -1); //解决周日会出现 并到下一周的情况    
          cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);    
          return cal.getTime();    
     }
	 
	/**
	 * 获取当前日期所在周的最后一天    
	 * @param date
	 * @return
	 */
	 public static Date getLastDayInWeek(Date date) {    
         Calendar cal = Calendar.getInstance();    
         cal.setTime(date);
		 cal.set(Calendar.DAY_OF_WEEK, cal.getActualMaximum(Calendar.DAY_OF_WEEK));
		 cal.add(Calendar.DAY_OF_WEEK, -6);
         return cal.getTime();    
    }

	public static String getLastDayInWeek(Date date, String format) {
		return DateUtils.formatDate(getLastDayInWeek(date), format);
	}
	 
	 /**
	  * 获取当前日期后几天的日期
	  * @param d
	  * @param day
	  * @return
	  */
	 public static Date getDateAfter(Date d, int day) {  
	        Calendar now = Calendar.getInstance();  
	        now.setTime(d);  
	        now.set(Calendar.DATE, now.get(Calendar.DATE) + day);  
	        return now.getTime();  
	    }

	 public static int compareDate1(Date dt1,Date dt2) throws ParseException{
		 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		 Date d1 = sdf.parse(sdf.format(dt1));
		 Date d2 = sdf.parse(sdf.format(dt2));
         if (d1.getTime() > d2.getTime()) {
             //System.out.println("dt1 在dt2前");
             return 1;
         } else if (d1.getTime() < d2.getTime()) {
             //System.out.println("dt1在dt2后");
             return -1;
         } else {//相等
             return 0;
         }
}
	/** */
	/**
	 * 获得这周的最后一天
	 * 
	 * @param dateStr
	 * @return
	 */
	public static String getLastDayInWeek(String dateStr) {
		if (checkParam(dateStr)) {
			return "";
		}
		Date date = parseStrToDate(dateStr);
		Locale locale = Locale.getDefault();
		Calendar calendar = new GregorianCalendar(locale);
		calendar.setTime(date);
		int lastDay = calendar.getActualMaximum(Calendar.DAY_OF_WEEK);
		calendar.set(Calendar.DAY_OF_WEEK, -6);

		return DateUtils.formatDate(calendar.getTime(), DateUtils.DATE_FORMAT);
	}

	/**
	 * 时间相加
	 * 
	 * @return
	 */
	public static Date addTimeHour(Date date, int minute) {
		if (checkParam(date)) {
			return null;
		}
		if (0 == minute) {
			return date;
		}
		Locale locale = Locale.getDefault();
		Calendar calendar = new GregorianCalendar(locale);
		calendar.setTime(date);
		calendar.add(Calendar.MINUTE, minute);
		return calendar.getTime();
	}

	/**
	 * 当前时间：以半小时为单位超过半小时按照一小时算
	 * 
	 * @return
	 */
	public static String currentTimeHour() {
		Locale locale = Locale.getDefault();
		Calendar calendar = new GregorianCalendar(locale);
		Date date = getCurrentDate();
		calendar.setTime(date);
		if (calendar.get(Calendar.MINUTE) <= 30) {
			calendar.set(Calendar.MINUTE, 30);
		} else {
			calendar.add(Calendar.HOUR_OF_DAY, 1);
			calendar.set(Calendar.MINUTE, 00);
		}
		return formatDate(calendar.getTime(), DateUtils.TIME_MIN_FORMAT);
	}

	/**
	 * 指定起始时间：以半小时为单位超过半小时按照一小时算
	 * 
	 * @return
	 */
	public static String specifyTimeHour(String specifyTime) {
		Locale locale = Locale.getDefault();
		Calendar calendar = new GregorianCalendar(locale);
		Date date = parseStrToDateTime(specifyTime);
		calendar.setTime(date);
		if (calendar.get(Calendar.MINUTE) <= 30) {
			calendar.set(Calendar.MINUTE, 30);
			calendar.set(Calendar.SECOND, 00);
		} else {
			calendar.add(Calendar.HOUR_OF_DAY, 1);
			calendar.set(Calendar.MINUTE, 00);
			calendar.set(Calendar.SECOND, 00);
		}
		return formatDate(calendar.getTime(), DateUtils.TIME_MIN_FORMAT);
	}

	/**
	 * 指定起始时间：以半小时为单位超过半小时按照一小时算
	 * 
	 * @return
	 */
	public static String specifyTimeHour(String specifyTime, String pattern) {
		Locale locale = Locale.getDefault();
		Calendar calendar = new GregorianCalendar(locale);
		Date date = parseStrToDateTime(specifyTime);
		calendar.setTime(date);
		if (calendar.get(Calendar.MINUTE) <= 30) {
			calendar.set(Calendar.MINUTE, 30);
			calendar.set(Calendar.SECOND, 00);
		} else {
			calendar.add(Calendar.HOUR_OF_DAY, 1);
			calendar.set(Calendar.MINUTE, 00);
			calendar.set(Calendar.SECOND, 00);
		}
		return formatDate(calendar.getTime(), pattern);
	}

	/**
	 * 当前时间：以半小时为单位超过半小时按照一小时算
	 * 
	 * @return
	 */
	public static String currentTimeHour(String pattern) {
		Locale locale = Locale.getDefault();
		Calendar calendar = new GregorianCalendar(locale);
		Date date = getCurrentDate();
		calendar.setTime(date);
		if (calendar.get(Calendar.MINUTE) <= 30) {
			calendar.set(Calendar.MINUTE, 30);
		} else {
			calendar.add(Calendar.HOUR_OF_DAY, 1);
			calendar.set(Calendar.MINUTE, 00);
		}
		return formatDate(calendar.getTime(), pattern);
	}

	/**
	 * 获得两个指定的时间差 单位为毫秒
	 * 
	 * @param startTime
	 * @param endTime
	 * @return
	 */
	public static long getTotalTime(String startTime, String endTime) {
		if (checkParam(startTime) || checkParam(endTime)) {
			return 0;
		}
		Calendar end = parseStrToCalendar(endTime);
		Calendar stard = parseStrToCalendar(startTime);

		return end.getTimeInMillis() - stard.getTimeInMillis();
	}

	/**
	 * 获得两个指定的天数差 单位为天
	 * @param startDay
	 * @param endDay
	 * @return
	 */
	public static int getDifferDays(Date startDay, Date endDay) {
		if (checkParam(startDay) || checkParam(endDay)) {
			return 0;
		}
		Locale locale = Locale.getDefault();
		Calendar start = new GregorianCalendar(locale);
		Calendar end = new GregorianCalendar(locale);
		start.setTime(startDay);
		end.setTime(endDay);
		int y = end.get(Calendar.YEAR) - start.get(Calendar.YEAR);
		if (y != 0)
			return end.get(Calendar.DAY_OF_YEAR) - start.get(Calendar.DAY_OF_YEAR) + 365 * y;
		else
			return end.get(Calendar.DAY_OF_YEAR) - start.get(Calendar.DAY_OF_YEAR);
	}
	
	/**
	 * 获得两个指定的年数差 单位为年
	 * 
	 * @param startDay
	 * @param endDay
	 * @return
	 * 
	 */
	public static int getTotalYear(Date startDay, Date endDay) {
		if (checkParam(startDay) || checkParam(endDay)) {
			return 0;
		}
		Locale locale = Locale.getDefault();
		Calendar start = new GregorianCalendar(locale);
		Calendar end = new GregorianCalendar(locale);
		start.setTime(startDay);
		end.setTime(endDay);
		int y = end.get(Calendar.YEAR) - start.get(Calendar.YEAR);
		return y;
	}

	/**
	 * 根据开始日期和结束日期得到时间间隔列表
	 * 
	 * @param startDay
	 * @param endDay
	 * @return
	 */
	public static List<String> getDaySlice(Date startDay, Date endDay) {
		int space = getDifferDays(startDay, endDay);
		List<String> spaceList = new ArrayList<String>();
		for (int i = 0; i <= space; i++) {
			Date dateSpace = addDays(startDay, i);
			spaceList.add(i, formatDate(dateSpace, DateUtils.DATE_FORMAT));
		}
		return spaceList;
	}

	/**
	 * 根据当前日期获取0点的时间
	 * @param date
	 * @return
	 * 
	 *         Date
	 * 
	 *         Created on Mar 29, 2007 11:10:43 AM
	 */
	public static Date convertDate(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.HOUR_OF_DAY, 00);
		calendar.set(Calendar.MINUTE, 00);
		calendar.set(Calendar.SECOND, 00);
		return calendar.getTime();
	}

	public static Date convertDate(Date date, String format) {
		return parseStrToDate(formatDate(date, format));
	}

	public static Date dateTimeOffset(Date dateTime) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(dateTime);
		if (calendar.get(Calendar.HOUR_OF_DAY) < 03) {
			if (calendar.get(Calendar.AM_PM) == 0) {
				calendar.setTime(addDays(calendar.getTime(), -1));
			}
		}
		calendar.set(Calendar.HOUR_OF_DAY, 03);
		calendar.set(Calendar.MINUTE, 00);
		calendar.set(Calendar.SECOND, 00);
		return calendar.getTime();
	}

	/**
	 * 根据当前日期获取整点的时间
	 * @param date
	 * @return
	 * 
	 *         Date
	 * 
	 */
	public static Date convertHour(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.MINUTE, 00);
		calendar.set(Calendar.SECOND, 00);
		return calendar.getTime();
	}
	
	/**
	 * Conversion offset.
	 * 
	 * 转化时间偏移格式
	 * 
	 * @param time
	 *                the time 单位(秒)
	 * 
	 * @return the string
	 * 
	 *         String
	 * 
	 *         Created on Apr 23, 2007 9:18:21 AM
	 */
	public static String conversionOffset(Long time) {

		Long leg = time;
		Long hour = leg / 3600;
		Long min = (leg % 3600) / 60;
		Long sec = leg % 60;
		StringBuffer buf = new StringBuffer();
		if (hour < 10) {
			buf.append("0");
		}
		buf.append(leg / 3600);
		buf.append(":");
		if (min < 10) {
			buf.append("0");
		}
		buf.append((leg % 3600) / 60);
		buf.append(":");
		if (sec < 10) {
			buf.append("0");
		}
		buf.append(leg % 60);
		return buf.toString();
	}

	/**
	 * 把日期格式化成字符串
	 * @param date
	 * @param fromat  
	 * @return
	 */
	public static String parseDateToString(Date date, String fromat) {
		SimpleDateFormat dateFormat = new SimpleDateFormat(fromat);
		return dateFormat.format(date);
	}
	
	/**
	 * 根据小时字符串获取小时所在日期
	 * @param hourStr
	 * @return
	 */
	public static Date getHourDate(String hourStr){
		if(checkParam(hourStr)){
			return null;
		}
		SimpleDateFormat dateFormat = new SimpleDateFormat(TIME_MIN_FORMAT);
		Date date = dateFormat.parse(hourStr, new ParsePosition(0));
		
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		int hour = calendar.get(Calendar.HOUR_OF_DAY);
		calendar.setTime(new Date());
		calendar.set(Calendar.HOUR_OF_DAY, hour);
		calendar.set(Calendar.MINUTE, 00);
		calendar.set(Calendar.SECOND, 00);
		return calendar.getTime();
	}
	
	public static String getWeekDay(String date, String format, String language) {
		int weekDay = 0;
		if (date != null && !"".equals(date)) {
			SimpleDateFormat currF = new SimpleDateFormat(format);
			Calendar c = Calendar.getInstance();
			try {
				Date df = currF.parse(date);
				c.setTime(df);
				int d = c.get(Calendar.DATE);
				c.set(Calendar.DATE, d - 1);
				weekDay = c.get(Calendar.DAY_OF_WEEK);
			} catch (ParseException e) {
				logger.error(null, e);
			}
		}
		return getWeekDay(weekDay, language);
	}

	public static String getWeekDay(int w, String language) {
		String weekDay = "";
		if (w > 0) {
			if (language != null && "zh_CN".equals(language)) {
				switch (w) {
				case 1:
					weekDay = "星期一";
					break;
				case 2:
					weekDay = "星期二";
					break;
				case 3:
					weekDay = "星期三";
					break;
				case 4:
					weekDay = "星期四";
					break;
				case 5:
					weekDay = "星期五";
					break;
				case 6:
					weekDay = "星期六";
					break;
				case 7:
					weekDay = "星期日";
					break;
				}
			} else {
				switch (w) {
				case 1:
					weekDay = "Monday";
					break;
				case 2:
					weekDay = "Tuesday";
					break;
				case 3:
					weekDay = "Wednesday";
					break;
				case 4:
					weekDay = "Thursday";
					break;
				case 5:
					weekDay = "Friday";
					break;
				case 6:
					weekDay = "Saturday";
					break;
				case 7:
					weekDay = "Sunday";
					break;
				}
			}
		}
		return weekDay;
	}
	
   /** 
    * 获取过去第几天的日期 
    * 
    * @param past 
    * @return 
    */  
   public static String getPastDate(int past) {  
       Calendar calendar = Calendar.getInstance();  
       calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) - past);  
       Date today = calendar.getTime();  
       SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");  
       String result = format.format(today);  
       return result;  
   }

	public static Map<String, String> buildQueryTime(QueryTimeDimension queryTimeDimension) {
		if (queryTimeDimension == null) return null;
		HashMap<String, String> queryTimeMap = new HashMap<>(2);
		Date date = new Date();
		switch (queryTimeDimension) {
			case TODAY:
				queryTimeMap.put("begin-date", formatDate(date, DATE_FORMAT));
				queryTimeMap.put("end-date", formatDate(date, DATE_FORMAT));
				break;
			case THIS_MONTH:
				queryTimeMap.put("begin-date", getFirstDayInMonth(formatDate(new Date(), DATE_FORMAT)));
				queryTimeMap.put("end-date", getLastDayInMonth(formatDate(new Date(), DATE_FORMAT)));
				break;
			case CUSTOM:
			case THIS_TERM:
				break;
			default:
				queryTimeMap.put("begin-date", getFirstDayInWeek(date, DATE_FORMAT));
				queryTimeMap.put("end-date", formatDate(getLastDayInWeek_(date), DATE_FORMAT));
		}
		return queryTimeMap;
	}

	public static List<String> getDaysInTimeSlot(String startTime, String endTime) {

		// 返回的日期集合
		List<String> days = new ArrayList<String>();
		DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		try {
			Date start = dateFormat.parse(startTime);
			Date end = dateFormat.parse(endTime);

			Calendar tempStart = Calendar.getInstance();
			tempStart.setTime(start);
			Calendar tempEnd = Calendar.getInstance();
			tempEnd.setTime(end);
			tempEnd.add(Calendar.DATE, +1);// 日期加1(包含结束)
			while (tempStart.before(tempEnd)) {
				days.add(dateFormat.format(tempStart.getTime()));
				tempStart.add(Calendar.DAY_OF_YEAR, 1);
			}

		} catch (ParseException e) {
			e.printStackTrace();
		}

		return days;
	}

	public static List<String> getMonthInTimeSlot(String beginD, String endD) {
		SimpleDateFormat format = new SimpleDateFormat(DATE_FORMAT);
		SimpleDateFormat monthFormat = new SimpleDateFormat("yyyy-MM");
		List<String> monthList = new ArrayList<>();
		try {
			Date begin = format.parse(beginD);
			Date end = format.parse(endD);
			int months = (end.getYear() - begin.getYear()) * 12
					+ (end.getMonth() - begin.getMonth());

			for (int i = 0; i <= months; i++) {
				Calendar calendar = Calendar.getInstance();
				calendar.setTime(begin);
				calendar.add(Calendar.MONTH, i);
				monthList.add(monthFormat.format(calendar.getTime()));
			}

		} catch (ParseException e) {
			logger.error(e.getMessage(), e.fillInStackTrace());
		}

		return monthList;
	}

	public static int daysBetween(String smdate,String bdate) {
		try {
			SimpleDateFormat sdf=new SimpleDateFormat(DATE_FORMAT);
			Calendar cal = Calendar.getInstance();
			cal.setTime(sdf.parse(smdate));
			long time1 = cal.getTimeInMillis();
			cal.setTime(sdf.parse(bdate));
			long time2 = cal.getTimeInMillis();
			long between_days=(time2-time1)/(1000*3600*24);
			return Integer.parseInt(String.valueOf(between_days));
		} catch (Exception e) {
			logger.error(e.getMessage(), e.fillInStackTrace());
		}
		return 0;

	}

	public static List<String> getWeekInTimeSlot(String startString, String endString) {
		List<String> list = new ArrayList<>();
		LocalDate start = toLocalDate(startString);
		LocalDate end = toLocalDate(endString);
		WeekFields weekFields = WeekFields.of(DayOfWeek.MONDAY,1);
		while (start.compareTo(end) <= 0) {
			// 为了匹配MYSQL的DATE_FORMAT(create_time,'%Y-%u') 进行-1操作
			list.add(start.getYear() + "-" + (start.get(weekFields.weekOfWeekBasedYear())));
			start = start.plusWeeks(1);
		}
		return list;
	}

	private static LocalDate toLocalDate(String str) {
		DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
		return LocalDate.parse(str, fmt);
	}

	public static Date getLastDayInWeek_(Date date) {
		TemporalField fieldISO = WeekFields.of(Locale.CHINA).dayOfWeek();
		Instant instant = date.toInstant();
		ZoneId zoneId = ZoneId.systemDefault();

		// atZone()方法返回在指定时区从此Instant生成的ZonedDateTime。
		LocalDate localDate = instant.atZone(zoneId).toLocalDate();

		localDate.with(fieldISO, 7);
		return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).plusDays(1L).minusNanos(1L).toInstant());
	}

	public static int getAge(Date birthDay) {
		Calendar cal = Calendar.getInstance();
		int yearNow = cal.get(Calendar.YEAR);  //当前年份
		int monthNow = cal.get(Calendar.MONTH);  //当前月份
		int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH); //当前日期
		cal.setTime(birthDay);
		int yearBirth = cal.get(Calendar.YEAR);
		int monthBirth = cal.get(Calendar.MONTH);
		int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);
		int age = yearNow - yearBirth;   //计算整岁数
		if (monthNow <= monthBirth) {
			if (monthNow == monthBirth) {
				if (dayOfMonthNow < dayOfMonthBirth) age--;//当前日期在生日之前，年龄减一
			}else{
				age--;//当前月份在生日之前，年龄减一

			}
		}
		return age;
   }


}
